#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2021/10/26
# @Author  : 邓大大
# @Desc    : ccxt 双均线策略

# 策略：天双均线策略 + 趋势策略
# 策略原理：运用两条不同周期的移动平均线，即短周期平均线与长周期平均线的相对大小判断买入卖出的交易点
# 当短周期移动平均线上窜长周期移动平均线时即为多头市场，金叉
# 当短周期移动平均线下窜长周期移动平均线时即为空头市场，死叉

# 步骤一：设置参数：长周期数、短周期数、交易频率（d\h\m）
import datetime
import time
import ccxt
import pandas as pd
import matplotlib.pyplot as plt


class TowAverageTactics(object):
    """双均线策略"""

    def __init__(self, long_period, short_period, deal_frequency, symbol, exchange_name, deal_tag):
        self.long_period = long_period  # 长周期数
        self.short_period = short_period  # 短周期数
        self.deal_frequency = deal_frequency  # 买入频率
        self.symbol = symbol  # 交易对
        self.exchange_name = exchange_name  # 交易所名称
        self.deal_tag = deal_tag
        # self.API_KEY = api_key
        # self.SECRET_KEY = secret_key

    def main(self):
        """主程序"""
        print("双均线策略开始")
        if self.exchange_name == "binance":
            self.my_exchange = ccxt.binance({
                "apiKey": None,
                "secret": None,
                'timeout': 15000,
                'enableRateLimit': True,
                'proxies': {
                    'http': 'http://127.0.0.1:58591',
                    'https': 'https://127.0.0.1:58591'}
            })
        elif self.exchange_name == "huobi":
            self.my_exchange = ccxt.huobi({
                "apiKey": '',
                "secret": '',
                'timeout': 15000,
                'enableRateLimit': True,
                'proxies': {
                    'http': 'http://127.0.0.1:58591',
                    'https': 'https://127.0.0.1:58591'}
            })
        long_period, short_period = self.average_line()
        short_list = short_period.tail().to_list()
        long_list = long_period.tail().to_list()
        # 如果短周期上穿长周期
        print("短期平均线前一天的值：{}".format(short_list[-2]))
        print("短期平均线当天的值：{}".format(short_list[-1]))
        if self.deal_tag:

            if long_list[-2] > short_list[-2] and long_list[-1] <= short_list[-1]:
                self.exchange_deal(way='buy')
            # 短周期下穿长周期
            elif long_list[-2] < short_list[-2] and long_list[-1] >= short_list[-1]:
                self.exchange_deal(way='sell')
            else:
                print('无交易')

    def average_line(self):
        """短期均线"""
        period_k = self.my_exchange.fetch_ohlcv(self.symbol, timeframe=self.deal_frequency)
        kline_data_df = pd.DataFrame(period_k)
        kline_data_df.columns = ['Datetime', 'Open', 'High', 'Low', 'Close', 'Vol']
        print('货币前一天的价:{}'.format(kline_data_df['Close'].to_list()[-1]))
        plt.plot([i for i in range(0, len(kline_data_df['Close'].to_list()[-100:]))],
                 kline_data_df['Close'].to_list()[-100:], color='y')

        long_period = kline_data_df['Close'].rolling(self.long_period).mean()
        plt.plot([i for i in range(0, len(long_period.to_list()[-100:]))], long_period.to_list()[-100:], color='g')

        short_period = kline_data_df['Close'].rolling(self.short_period).mean()
        plt.plot([i for i in range(0, len(short_period.to_list()[-100:]))], short_period.to_list()[-100:], color='r')
        plt.legend(['price_kling', 'long_average_kling', 'short_average_kling'], loc='upper right', fontsize=10)
        plt.savefig('/Users/denghui/Desktop/average_img/{}.png'.format(datetime.datetime.today()), dpi=100)
        plt.close()
        return long_period, short_period

    def get_price(self):
        """获取买价，卖价"""
        order_book = self.my_exchange.fetch_order_book(self.symbol)
        # 最高买价
        high_p = order_book['bids'][0][0] if len(order_book['bids']) > 0 else None
        # 最低卖价
        low_p = order_book['asks'][0][0] if len(order_book['asks']) > 0 else None
        return high_p, low_p

    def exchange_deal(self, way='buy'):
        """获取"""
        coin1, coin2 = self.symbol.split('/')
        d = self.my_exchange.fetch_balance()
        if self.my_exchange.has['createLimitOrder']:
            high_p, low_p = self.get_price()
            if way == 'buy' and d[coin2]['total'] > 0.01:
                print('以最高买价{}买入{}个{}'.format(high_p, round(d[coin2]['total'] / high_p, 4), self.symbol))
                self.my_exchange.create_order(symbol=self.symbol, side=way, type='limit', price=high_p,
                                              amount=round(d[coin2]['total'] / high_p, 4))

            elif way == 'sell' and d[coin1]['total'] > 0.01:
                print('以最低卖价{}卖出{}个{}'.format(low_p, round(d[coin1]['total'], 4), self.symbol))
                self.my_exchange.create_order(symbol=self.symbol, side=way, type='limit', price=low_p,
                                              amount=d[coin1]['total'])
            else:
                print(datetime.datetime.today(), "无交易")
        while True:
            if self.my_exchange.has['fetchOpenOrders']:
                open_orders = self.my_exchange.fetch_open_orders(self.symbol)
                if open_orders:
                    print('委托单还未被吃单')
                    time.sleep(60)
                else:
                    print('交易完成')
                    break


if __name__ == '__main__':
    while True:
        try:
            ex = TowAverageTactics(long_period=20, short_period=5, deal_frequency='1h', symbol='YGG/USDT',
                                   exchange_name='huobi', deal_tag=True)
            ex.main()
            print("程序睡眠一天")
            time.sleep(60 * 60)
        except Exception as e:
            print('执行报错:{}'.format(repr(e)))
